import json
import uuid

from alibabacloud_dingtalk.robot_1_0.client import Client as dingtalkrobot_1_0Client
from alibabacloud_dingtalk.im_1_0.client import Client as dingtalkim_1_0Client

from alibabacloud_dingtalk.robot_1_0 import models as dingtalkrobot__1__0_models
from alibabacloud_dingtalk.im_1_0 import models as dingtalkim__1__0_models
from alibabacloud_tea_util import models as util_models
# from alibabacloud_tea_util.client import Client as UtilClient
from django.conf import settings

from core.base import ding_client, ding_ding_token


class HttpRequest(object):
    def __init__(self, client_class, headers_obj):
        self.headers = headers_obj
        self.headers.x_acs_dingtalk_access_token = ding_ding_token()
        self.client = ding_client(client_class)

    def _execute(self, execute_name, request):
        execute = getattr(self.client, execute_name)
        response = execute(request, self.headers, util_models.RuntimeOptions())
        return response


class OtoRequest(HttpRequest):
    def __init__(self):
        client_class = dingtalkrobot_1_0Client
        headers_obj = dingtalkrobot__1__0_models.BatchSendOTOHeaders()
        super(OtoRequest, self).__init__(client_class, headers_obj)

    def post_msg(self, msg_key, msg_param, user_ids) -> dingtalkrobot__1__0_models.BatchSendOTOResponse:
        # 发送请求方法名称
        execute_name = 'batch_send_otowith_options'

        # 构造钉钉sdk请求对象
        request = dingtalkrobot__1__0_models.BatchSendOTORequest()

        # 设置发送消息机器人的id
        request.robot_code = settings.DING_ROBOT_ID

        # 设置消息模板的key名称
        request.msg_key = msg_key

        # 将发送消息字段转为json字符串并设置消息字段
        msg_param = json.dumps(msg_param)
        request.msg_param = msg_param

        # 设置接收消息的用户名称
        request.user_ids = user_ids

        # 执行钉钉sdk发送单聊消息请求
        response = self._execute(execute_name=execute_name, request=request)
        return response

    # 发送纯文本消息
    def post_official_text_msg(self, content=None, user_ids=None):
        msg_key = 'officialTextMsg'
        msg_param = {
            "content": content
        }
        user_ids = user_ids
        return self.post_msg(msg_key=msg_key, msg_param=msg_param, user_ids=user_ids)

    # 发送纯图片消息
    def post_official_image_msg(self, photo_url, user_ids):
        msg_key = 'officialImageMsg'
        msg_param = {
            "photoURL": photo_url
        }
        user_ids = user_ids
        return self.post_msg(msg_key=msg_key, msg_param=msg_param, user_ids=user_ids)


class InteractiveCardRequest(HttpRequest):
    """
    发送单聊消息说明
    调用发送动态卡片接口时 不需要传入 openConversationId
    receiverUserIdList 只传一个userid， conversationType 选择单聊，chatBotId 不需要填写。
    还有接口传入的token需要是企业内部机器人的，并且该机器人已上线。
    """

    def __init__(self, send_mode):
        # 卡片发送方式
        self.send_mode = send_mode

        # 卡片操作回调key
        callback_route_keys = dict(settings.CALLBACK_ROUTE_KEYS)

        # 判断是IM卡片还是吊顶卡片
        if self.send_mode in ('private', 'group'):
            self.callback_route_key = callback_route_keys.get('IM_card')
            headers_obj = dingtalkim__1__0_models.SendInteractiveCardHeaders()
            self.card_data_class = dingtalkim__1__0_models.SendInteractiveCardRequestCardData
        elif self.send_mode == 'top':
            self.callback_route_key = callback_route_keys.get('top_card')
            self.card_data_class = dingtalkim__1__0_models.InteractiveCardCreateInstanceRequestCardData
            headers_obj = dingtalkim__1__0_models.InteractiveCardCreateInstanceHeaders()

        # 客户端类
        client_class = dingtalkim_1_0Client
        super(InteractiveCardRequest, self).__init__(client_class, headers_obj)

    def set_out_track_id(self, request):
        out_track_id = uuid.uuid4().hex
        setattr(self, 'out_track_id', out_track_id)
        request.out_track_id = self.out_track_id

    # IM卡片数据发送
    def send(self, card) -> dingtalkim__1__0_models.SendInteractiveCardResponseBody:
        # 发送请求方法名称
        execute_name = 'send_interactive_card_with_options'

        # 构造钉钉sdk请求对象
        request = dingtalkim__1__0_models.SendInteractiveCardRequest()

        card_data_map = card.get('card_data_map')
        card_type = card.get('card_type')

        # 通用参数
        self._general_params(request, card_data_map, card_type)

        # IM卡片参数
        chat = getattr(self, self.send_mode)
        chat(request)
        return self._execute(execute_name=execute_name, request=request)

    # 通用参数
    def _general_params(self, request, card_data_map, card_type, card_template_id):
        # 消息模板id
        request.card_template_id = card_template_id

        # 互动卡片id
        self.set_out_track_id(request)

        # 用户id类型，使用默认的userid
        user_id_type = 1
        request.user_id_type = user_id_type

        # 设置卡片数据
        if card_type == 'nomal':
            card_data = self.card_data_class(
                card_param_map=card_data_map,
            )
        if card_type == 'media':
            card_data = self.card_data_class(
                card_data_card_media_id_param_map=card_data_map,
            )
        request.card_data = card_data

    # 群聊配置
    def group(self, request: dingtalkim__1__0_models.SendInteractiveCardRequest):
        # 群聊会话类型
        conversation_type = 1
        request.conversation_type = conversation_type

        # 群聊的id
        open_conversation_id = settings.OPEN_CONVERSATION_ID_1
        request.open_conversation_id = open_conversation_id

        # 设置发送消息机器人的id
        robot_code = settings.ROBOT_1
        request.robot_code = robot_code

        # 艾特的人列表
        at_open_ids = []
        if at_open_ids:
            request.at_open_ids = at_open_ids

    # 单聊配置
    def private(self, request: dingtalkim__1__0_models.SendInteractiveCardRequest):
        # 单聊会话类型
        conversation_type = 0
        request.conversation_type = conversation_type

        # 发送人的id
        receiver_user_id_list = ['142934503420201038']
        request.receiver_user_id_list = receiver_user_id_list

    # 吊顶卡片配置
    def create_instance(self, card_data_map, card_type):
        # 发送请求方法名称
        execute_name = 'interactive_card_create_instance_with_options'

        # 构造钉钉sdk请求对象
        request = dingtalkim__1__0_models.InteractiveCardCreateInstanceRequest()

        # 通用参数
        self._general_params(request, card_data_map, card_type)

        # 设置群聊参数
        # self.group(request)

        return self._execute(execute_name=execute_name, request=request)

    # 吊顶卡片开启置顶
    def send_top(self, card, expired_time=None):
        card_data_map = card.get('card_data_map')
        card_type = card.get('card_type')

        # 创建置顶卡片实例
        response = self.create_instance(card_data_map, card_type)

        headers_obj = dingtalkim__1__0_models.TopboxOpenHeaders()
        _self = HttpRequest(dingtalkim_1_0Client, headers_obj)

        # 发送请求方法名称
        execute_name = 'topbox_open_with_options'

        # 构造钉钉sdk请求对象
        request = dingtalkim__1__0_models.TopboxOpenRequest()

        # 群聊的id
        open_conversation_id = settings.OPEN_CONVERSATION_ID_1
        request.open_conversation_id = open_conversation_id

        # 互动卡片id
        request.out_track_id = self.out_track_id

        # 过期时间设置
        if expired_time:
            request.expired_time = expired_time
        return _self._execute(execute_name=execute_name, request=request)


class UpdateInteractiveCardRequest(HttpRequest):
    def __init__(self, out_track_id):
        self.out_track_id = out_track_id
        client_class = dingtalkrobot_1_0Client
        headers_obj = dingtalkrobot__1__0_models.UpdateInteractiveCardHeaders()
        super(UpdateInteractiveCardRequest, self).__init__(client_class, headers_obj)

    def set_options(self, is_by_key=None, is_private_by_key=None):
        pass

    def update(self, **kwargs):
        card_data_map = kwargs
        card_data = dingtalkim__1__0_models.UpdateInteractiveCardRequestCardData(
            card_param_map=card_data_map,
            card_media_id_param_map=card_data_map
        )
